package com.linkhub.oms.admin.modules.order.domain.vo;

import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.collection.CollUtil;
import com.linkhub.oms.common.util.QtStreamUtil;
import com.linkhub.oms.common.util.json.QtFastjsonUtil;
import com.linkhub.oms.data.sync.api.yunexpress.domain.response.CreateOrderResponse;
import com.linkhub.oms.entity.OrderEntity;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author Jaycle
 * @version 1.0.0
 * @Description EmployeeOrderForecastResultVO.java
 * @createTime 2024/07/06 14:41
 */
@Data
@ApiModel("订单预报结果对象")
public class EmployeeOrderForecastResultVO implements Serializable{

    @ApiModelProperty("成功数量")
    private int successTotal;

    @ApiModelProperty("失败数量，数量 > 0 才有失败原因")
    private int failTotal;

    @ApiModelProperty("失败原因")
    private String failReason;

    public static OrderFulfillmentResultVO createFailResult(String failReason, int failTotal) {
        OrderFulfillmentResultVO vo = new OrderFulfillmentResultVO();
        vo.setSuccessTotal(0);
        vo.setFailTotal(failTotal);
        vo.setFailReason(failReason);

        return vo;
    }

    public static OrderFulfillmentResultVO createResult(int successTotal, int failTotal, String failReason) {
        OrderFulfillmentResultVO vo = new OrderFulfillmentResultVO();
        vo.setSuccessTotal(successTotal);
        if (failTotal < 1) {
            return vo;
        }
        vo.setFailTotal(failTotal);
        vo.setFailReason(failReason);

        return vo;
    }

    public static OrderFulfillmentResultVO createResult(int total,
                                                        List<OrderEntity> emptyLogisticOrders,
                                                        List<OrderEntity> insufficientBalanceOrders) {

        OrderFulfillmentResultVO vo = new OrderFulfillmentResultVO();
        StringBuilder failReason = new StringBuilder();
        if (CollUtil.isNotEmpty(emptyLogisticOrders)) {
            failReason.append(String.format("The logistics mode is empty, orderNumbers: [%s]\n",
                    QtFastjsonUtil.toJSONString(QtStreamUtil.map(emptyLogisticOrders, order -> String.valueOf(order.getOrderNumber())))));
        }

        if (CollUtil.isNotEmpty(insufficientBalanceOrders)) {
            failReason.append(String.format("Insufficient available balance, orderNumbers: [%s]",
                    QtFastjsonUtil.toJSONString(QtStreamUtil.map(insufficientBalanceOrders, order -> String.valueOf(order.getOrderNumber())))));
        }

        int failTotal = CollUtil.size(emptyLogisticOrders) + CollUtil.size(insufficientBalanceOrders);
        vo.setFailTotal(failTotal);

        if (failTotal > 0) {
            vo.setFailReason(failReason.toString());
        }

        vo.setSuccessTotal(total - failTotal);

        return vo;

    }

    public static EmployeeOrderForecastResultVO createResult( List<OrderEntity> pendingForecastOrders, Map<Boolean, List<OrderEntity>> partitionPendingForecastOrders, List<CreateOrderResponse.Item> responseItems ) {
        EmployeeOrderForecastResultVO vo = new EmployeeOrderForecastResultVO();
        StringBuilder failReason = new StringBuilder();
         List<OrderEntity> noLocalProductOrder = partitionPendingForecastOrders.get(false);
        if (CollUtil.isNotEmpty(noLocalProductOrder)) {
            failReason.append(String.format("The orders have not yet been localized products, orderNumbers: [%s]%n",
                    QtFastjsonUtil.toJSONString(QtStreamUtil.map(noLocalProductOrder, order -> String.valueOf(order.getOrderNumber())))));
        }

        if (CollUtil.isNotEmpty(responseItems)) {

            // 创建一个 sysOrderId 到 orderNumber 的映射
            Map<String, String> orderIdToOrderNumberMap = pendingForecastOrders.stream()
                    .collect(Collectors.toMap(OrderEntity::getSysOrderId, OrderEntity::getOrderNumber));
            responseItems.forEach(item -> {
                String orderNumber = orderIdToOrderNumberMap.get(item.getCustomerOrderNumber());
                String remark = item.getRemark();
                if (orderNumber != null) {
                    failReason.append(String.format("The orderNumber [%s] forecast failed, reason: [%s]%n",
                            orderNumber, remark));
                }
            });
        }

        int total = CollUtil.size(pendingForecastOrders);
        int failTotal = CollUtil.size(noLocalProductOrder) + CollUtil.size(responseItems);
        vo.setFailTotal(failTotal);

        if (failTotal > 0) {
            vo.setFailReason(failReason.toString());
        }

        vo.setSuccessTotal(total - failTotal);

        return vo;
    }
}
